package com.google.code.hostsman.db;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class DataSource {

	// Database fields
	private SQLiteDatabase database;
	private DatabaseOpenHelper dbHelper;

	public DataSource(Context context) {
		dbHelper = new DatabaseOpenHelper(context);
	}

	public void open() throws SQLException {
		database = dbHelper.getWritableDatabase();
	}

	public void close() {
		dbHelper.close();
	}

	public Group createGroup(Group group) {
		Log.i(DataSource.class.getName(), "Group created with name: " + group.getName());
		ContentValues values = new ContentValues();
		values.put(DatabaseContract.GroupEntry.COLUMN_NAME_NAME, group.getName());
		values.put(DatabaseContract.GroupEntry.COLUMN_NAME_ENABLED, group.isEnabled() ? DatabaseContract.BOOLEAN_TRUE : DatabaseContract.BOOLEAN_FALSE);
		long insertId = database.insert(DatabaseContract.GroupEntry.TABLE_NAME,
				null, values);
		
		group.setId(insertId);

		return group;
	}

	public void deleteGroup(Group group) {
		deleteGroup(group.getId());
	}

	public void deleteGroup(long groupId) {
		Log.i(DataSource.class.getName(), "Group deleted with id: " + groupId);
		database.delete(DatabaseContract.GroupEntry.TABLE_NAME,
				DatabaseContract.GroupEntry._ID + " = " + groupId, null);
	}
	
	public void updateGroup(Group group) {
		Log.i(DataSource.class.getName(),"Update group: "+group);
		ContentValues values=new ContentValues();
		values.put(DatabaseContract.GroupEntry.COLUMN_NAME_NAME, group.getName());
		values.put(DatabaseContract.GroupEntry.COLUMN_NAME_ENABLED, group.isEnabled());
		database.update(DatabaseContract.GroupEntry.TABLE_NAME, values, DatabaseContract.GroupEntry._ID+"="+group.getId(), null);
	}
	
	public Group getGroup(long groupId) {
		Cursor cursor = database.query(DatabaseContract.GroupEntry.TABLE_NAME,
				DatabaseContract.GroupEntry.ALL_COLUMNS, DatabaseContract.GroupEntry._ID+"="+groupId, null, null,
				null, null);

		cursor.moveToFirst();
		Group group = cursorToGroup(cursor);
		cursor.close();
		
		return group;
	}

	public List<Group> getAllGroups() {
		List<Group> list = new ArrayList<Group>();

		Cursor cursor = database.query(DatabaseContract.GroupEntry.TABLE_NAME,
				DatabaseContract.GroupEntry.ALL_COLUMNS, null, null, null,
				null, null);

		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Group group = cursorToGroup(cursor);
			list.add(group);
			cursor.moveToNext();
		}
		// make sure to close the cursor
		cursor.close();
		return list;
	}

	private Group cursorToGroup(Cursor cursor) {
		Group group = new Group();
		group.setId(cursor.getLong(0));
		group.setName(cursor.getString(1));
		group.setEnabled(cursor.getInt(2) == DatabaseContract.BOOLEAN_TRUE);
		return group;
	}
	
	public DomainIPPair createPair(DomainIPPair pair) {
		Log.i(DataSource.class.getName(), "DoaminIPPair created: "+pair);
		ContentValues values = new ContentValues();
		values.put(DatabaseContract.DomainIPPairEntry.COLUMN_NAME_DOMAIN, pair.getDomain());
		values.put(DatabaseContract.DomainIPPairEntry.COLUMN_NAME_IP, pair.getIp());
		values.put(DatabaseContract.DomainIPPairEntry.COLUMN_NAME_GROUP_ID, pair.getGroupId());
		long insertId = database.insert(DatabaseContract.DomainIPPairEntry.TABLE_NAME,
				null, values);
		
		pair.setId(insertId);

		return pair;
	}
	
	public void deletePair(DomainIPPair pair) {
		deletePair(pair.getId());
	}
	
	public void deletePair(long pairId) {
		Log.i(DataSource.class.getName(), "DomainIPPair deleted with id: " + pairId);
		database.delete(DatabaseContract.DomainIPPairEntry.TABLE_NAME,
				DatabaseContract.DomainIPPairEntry._ID + " = " + pairId, null);
	}
	
	public void updatePair(DomainIPPair pair) {
		Log.i(DataSource.class.getName(),"Update pair: "+pair);
		ContentValues values=new ContentValues();
		values.put(DatabaseContract.DomainIPPairEntry.COLUMN_NAME_DOMAIN, pair.getDomain());
		values.put(DatabaseContract.DomainIPPairEntry.COLUMN_NAME_IP, pair.getIp());
		values.put(DatabaseContract.DomainIPPairEntry.COLUMN_NAME_GROUP_ID, pair.getGroupId());
		database.update(DatabaseContract.DomainIPPairEntry.TABLE_NAME, values, DatabaseContract.DomainIPPairEntry._ID+"="+pair.getId(), null);
	}
	
	public List<DomainIPPair> getAllPairsInGroup(long groupId) {
		return getAllPairs(DatabaseContract.DomainIPPairEntry.COLUMN_NAME_GROUP_ID+"="+groupId);
	}
	
	public List<DomainIPPair> getAllDomainIPPairs() {
		return getAllPairs(null);
	}
	
	private List<DomainIPPair> getAllPairs(String selection) {
		List<DomainIPPair> list = new ArrayList<DomainIPPair>();

		Cursor cursor = database.query(DatabaseContract.DomainIPPairEntry.TABLE_NAME,
				DatabaseContract.DomainIPPairEntry.ALL_COLUMNS, selection, null, null,
				null, null);

		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			DomainIPPair pair = cursorToPair(cursor);
			list.add(pair);
			cursor.moveToNext();
		}
		// make sure to close the cursor
		cursor.close();
		return list;
	}
	
	private DomainIPPair cursorToPair(Cursor cursor) {
		DomainIPPair pair = new DomainIPPair();
		pair.setId(cursor.getLong(0));
		pair.setDomain(cursor.getString(1));
		pair.setIp(cursor.getString(2));
		pair.setGroupId(cursor.getLong(3));
		return pair;
	}
}